home *** CD-ROM | disk | FTP | other *** search
/ SGI Performance Co-Pilot 1.3 / SGI Performance Co-Pilot 1.3.iso / dist / pcp_gifts.idb / usr / sbin / dkmap.z / dkmap
Text File  |  1997-04-03  |  9KB  |  414 lines

  1. #!/bin/sh
  2. #
  3. # Produce a map of disk real estate usage
  4. #
  5. # $Header: /isms/npcp/pcp/1.3/gifts/dkmap/RCS/dkmap.sh,v 2.2 1997/03/21 07:06:04 kenmcd Exp $
  6. #
  7. # todo:
  8. #   - nested volume manager definitions?
  9. #   - other dbms products
  10. #   - partition overlap/containment?
  11. #   - identification of unuseable space (not in any partition)
  12. #    ... can this happen?
  13. #
  14.  
  15. status=0
  16. trap "rm -f /tmp/$$*; exit \$status" 0 1 2 3 15
  17. prog=`basename $0`
  18. sflag=false
  19. oflag=false
  20. DEBUG=false
  21. PATH=$PATH:/etc:/usr/local/bin ; export PATH
  22.  
  23. while [ $# -gt 0 ]
  24. do
  25.     case $1
  26.     in
  27.     -s)
  28.         # get disks from sar instead of hinv
  29.         sflag=true
  30.         ;;
  31.  
  32.     -o)    # include Oracle disk information
  33.         oflag=true
  34.         ;;
  35.  
  36.     -d)    # DEBUG
  37.         DEBUG=true
  38.         ;;
  39.  
  40.     *)
  41.         echo "Usage: dkmap [options]"
  42.         echo ""
  43.         echo "Options"
  44.         echo " -d    turn debug on .. see _lvol and _map.* files"
  45.         echo " -s    get disks from sar, not hinv"
  46.         echo " -o    include information for Oracle disks"
  47.         exit 1
  48.         ;;
  49.     esac
  50.     shift
  51. done
  52.  
  53. id=`id | sed -e 's/(.*//' -e 's/.*=//'`
  54. if [ $id != 0 ]
  55. then
  56.     echo "$prog: must be run as root"
  57.     exit 1
  58. fi
  59.  
  60. if $sflag
  61. then
  62.     #
  63.     # get list of disks that are alive from sar
  64.     #
  65.     sar -d 1 1 \
  66.     | sed -e '1,4d' \
  67.       -e 's/^.........//' \
  68.       -e 's/^ *//' \
  69.       -e 's/ .*//'
  70. else
  71.     #
  72.     # construct list of disks from hinv
  73.     #
  74.     hinv \
  75.     | sed -e 's/://g' -e 's/, lun/ lun/' \
  76.     | nawk '
  77. /Disk drive .* on SCSI .* RAID/{ printf "rad%sd%s\n",$8,$4; next }
  78. /Disk drive .* lun .* on SCSI /    { printf "dks%sd%sl%s\n",$10,$4,$6; next }
  79. /Disk drive .* on SCSI /    { printf "dks%sd%s\n",$8,$4; next }
  80. /Disk drive .* on VME-SCSI /    { printf "jag%sd%s\n",$8,$4; next }'
  81. fi >/tmp/$$.map
  82. $DEBUG && cp /tmp/$$.map _map.0
  83.  
  84. if [ -s /tmp/$$.map ]
  85. then
  86.     :
  87. else
  88.     echo "$prog: could find any disks?"
  89.     status=1
  90.     exit
  91. fi
  92.  
  93. #
  94. # use prtvtoc to get partiton table for each disk
  95. #
  96. lastdnum=x
  97. i=0
  98. rm -f /tmp/$$_*
  99. for dk in `sort -td +2 -3 /tmp/$$.map`
  100. do
  101.     dnum=`echo $dk | sed -e 's/.*d//'`
  102.     if [ $dnum != $lastdnum ]
  103.     then
  104.     if [ $i -gt 0 ]
  105.     then
  106.         wait
  107.         cat /tmp/$$_* >>/tmp/$$
  108.         rm -f /tmp/$$_*
  109.         i=0
  110.     fi
  111.     lastdnum=$dnum
  112.     fi
  113.     if /usr/pcp/bin/dkping /dev/rdsk/${dk}vh >/dev/null 2>&1
  114.     then
  115.     ( prtvtoc /dev/rdsk/${dk}vh \
  116.     | sed -e '1,/^Partition/d' \
  117.           -e '/volhdr/d' \
  118.           -e '/volume/d' \
  119.           -e 's/[()]/ /g' \
  120.     | nawk '
  121. NF==6    { print "'$dk's" $1,$2,$3,$3+$5-1 }
  122. NF==8    { print "'$dk's" $1,$2,$4,$4+$6-1,$8 }' \
  123.         >/tmp/$$_$i ) &
  124.     i=`expr $i + 1`
  125.     else
  126.     echo "$prog: Warning: no response from /dev/rdsk/${dk}, will be skipped"
  127.     fi
  128. done
  129.  
  130. if [ $i -gt 0 ]
  131. then
  132.     wait
  133.     cat /tmp/$$_* >>/tmp/$$
  134.     rm -f /tmp/$$_*
  135. fi
  136.  
  137. sort /tmp/$$ >/tmp/$$.map
  138. $DEBUG && cp /tmp/$$.map _map.1
  139.  
  140. #
  141. # find the mounted file systems
  142. # - this is more accurate/recent than prtvtoc ...
  143. #
  144. mount \
  145. | egrep 'type efs|type xfs' \
  146. | sed -e 's,/dev/dsk/,,' \
  147.       -e 's/ on / /' \
  148.       -e 's/ type \([^ ]*\) .*/ \1/' \
  149. | sort >/tmp/$$.mount
  150.  
  151. join -a1 -o 1.1 1.2 1.3 1.4 1.5 2.2 1.6 2.3 /tmp/$$.map /tmp/$$.mount \
  152. | nawk '
  153. NF <= 5    { print; next }
  154. NF == 6    { print $1,$6,$3,$4,$5; next }
  155. NF == 7    { print $1,$7,$3,$4,$6; next }' >/tmp/$$
  156. sort +0 -1 /tmp/$$ >/tmp/$$.map
  157. $DEBUG && cp /tmp/$$.map _map.4
  158.  
  159. #
  160. # find and match up swap partitions
  161. #
  162. ls -l /dev/rdsk | grep "`ls -l /dev/rswap | nawk '{ print $5 \"  *\" $6 }'`" \
  163. | nawk '{ print $NF}' >/tmp/$$
  164.  
  165. swap -l \
  166. | sed -e 1d -e "s,/dev/swap,`cat /tmp/$$`," \
  167. | nawk '{ print $2,"swap" }' \
  168. | sort >/tmp/$$.swap
  169.  
  170. join -a1 /tmp/$$.map /tmp/$$.swap >/tmp/$$
  171. mv /tmp/$$ /tmp/$$.map
  172. $DEBUG && cp /tmp/$$.map _map.2
  173.  
  174. #
  175. # expand any volume manager volumes into their constituent pieces and
  176. # match this up
  177. #
  178. touch /tmp/$$.lvol
  179. lvinfo \
  180. | sed -e '/^#/d' \
  181.       -e '/^ *$/d' \
  182.       -e '/\\$/{
  183. : loop
  184. N
  185. s/\\\n//
  186. t loop
  187. }' \
  188.       -e 's/,[     ]*/ /g' \
  189.       -e 's,/dev/dsk/,,g' \
  190.       -e 's/:.*devs= */ /' \
  191. | nawk '{ for (i=2; i<=NF; i++) print $i " " $1 " (part-" i-2 ")" }' >>/tmp/$$.lvol
  192.  
  193. #
  194. # xlv volumes ...
  195. #
  196. if [ -d /dev/rdsk/xlv ]
  197. then
  198.     for vol in `ls /dev/rdsk/xlv`
  199.     do
  200.     # I know this is hard to believe, but this is the interface we have
  201.     # to work with!
  202.     #
  203.     echo '42
  204. '$vol'
  205. 99' \
  206.     | xlv_admin 2>/dev/null \
  207.     | nawk '
  208. BEGIN            { p = 0 }
  209. state == 1 && NF == 0    { exit }
  210. /blks\)/        { state = 1
  211.               print $1 " '$vol' (part-" p ")"
  212.               p++
  213.             }' \
  214.     | sed -e 's;/dev/dsk/;;' >>/tmp/$$.lvol
  215.     done
  216. fi
  217.  
  218. sort -o /tmp/$$.lvol /tmp/$$.lvol
  219. $DEBUG && cp /tmp/$$.lvol _lvol
  220.  
  221. join -a1 -o 1.1 1.2 2.2 1.3 1.4 1.5 2.3 /tmp/$$.map /tmp/$$.lvol \
  222. | nawk '
  223. $NF ~ /^\(part-/    { print $1,$3,$4,$5,$6,$7; next }
  224. $2 == "lvol"        { print $0," (!config)"; next }
  225. $2 == "xlv"        { print $0," (!config)"; next }
  226.             { print }' >/tmp/$$
  227. sort +1 -2 /tmp/$$ >/tmp/$$.map
  228. $DEBUG && cp /tmp/$$.map _map.3
  229.  
  230. #
  231. # find the mounted file systems for the logical volumes
  232. #
  233. mount \
  234. | egrep 'lv|xlv' \
  235. | sed -e 's,/dev/dsk/,,' \
  236.       -e 's,^xlv/,,' \
  237.       -e 's/ on / /' \
  238.       -e 's/ type.*//' \
  239. | sort >/tmp/$$.mount
  240.  
  241. join -j1 2 -a1 -o 1.1 1.2 1.3 1.4 1.5 2.2 1.6 /tmp/$$.map /tmp/$$.mount >/tmp/$$
  242. sort +0 -1 /tmp/$$ >/tmp/$$.map
  243. $DEBUG && cp /tmp/$$.map _map.5
  244.  
  245. if [ "X$ORACLE_HOME" != X -a "X$ORACLE_SID" != X ]
  246. then
  247.     #
  248.     # dredge in Oracle
  249.     #
  250.     # oracle sys account [defaults - may have to be changed]
  251.     ora_sys=sys
  252.     ora_pw=change_on_install
  253.     PATH=$PATH:$ORACLE_HOME/bin ; export PATH
  254.  
  255.     cat >/tmp/$$.sh <<End-of-File
  256. sqlplus <<'End-of-SQL'
  257. $ora_sys/$ora_pw
  258. set pagesize 9999
  259. set linesize 9999
  260. select    substr(tablespace_name,1,28) "Tablespace", substr(file_name,1,50) "File"
  261. from    dba_data_files;
  262.  
  263. select    substr(member,1,50) "Log File", group#
  264. from    v\$logfile;
  265. End-of-SQL
  266. End-of-File
  267.  
  268.     if $oflag
  269.     then
  270.     #
  271.     # only oradev can run sqlplus!
  272.     #
  273.     su oradev -c "sh /tmp/$$.sh" >/tmp/$$.sql
  274.     status=$?
  275.     else
  276.     #
  277.     # sane state
  278.     #
  279.     sh /tmp/$$.sh >/tmp/$$.sql
  280.     status=$?
  281.     fi
  282.     $DEBUG && cp /tmp/$$.sh _sh
  283.     $DEBUG && cp /tmp/$$.sql _sql
  284.  
  285.     [ $status != 0 ] && echo "$prog: Warning: exit status $status from Oracle's SQLPLUS"
  286.  
  287.     rm -f /tmp/$$.err
  288.     sed </tmp/$$.sql \
  289.     -e '1,/^-----/d' \
  290.     -e '/Disconnected from ORACLE/,$d' \
  291.     -e '/^SQL> /d' \
  292.     -e '/^[     ]*$/d' \
  293.     -e '/Tablespace/d' \
  294.     -e '/^----/d' \
  295.     -e '/rows selected/d' \
  296.     -e 's/^[     ]*//' \
  297.     -e 's/[     ][     ]*/ /g' \
  298.     | nawk '
  299. /ERROR/        { print "_E_R_R_O_R_",$0; exit }
  300. /Log File/    { state = 1; next }
  301. state == 0    { print; next }
  302. state == 1    { print "TXLOG." $2,$1 }' \
  303.     | while read tblespace dev
  304.     do
  305.     if [ "$tblespace" = "_E_R_R_O_R_" ]
  306.     then
  307.         cat /tmp/$$.sql >/tmp/$$.err
  308.         echo "$prog: Oracle SQLPLUS error ... sorry" >>/tmp/$$.err
  309.         break
  310.     fi
  311.     slink=true
  312.     while $slink
  313.     do
  314.         if [ -l $dev ]
  315.         then
  316.         dev=`ls -ld $dev | sed -e 's/.* -> //'`
  317.         else
  318.         slink=false
  319.         if [ -f $dev ]
  320.         then
  321.             type=file
  322.         elif [ -c $dev ]
  323.         then
  324.             type=raw
  325.         else
  326.             type=unknown
  327.         fi
  328.         fi
  329.     done
  330.     case $dev
  331.     in
  332.         /dev/rdsk/lv*)
  333.         lv=`echo $dev | sed -e 's,/dev/rdsk/,,'`
  334.         grep " $lv " /tmp/$$.lvol >/tmp/$$
  335.         if [ -s /tmp/$$ ]
  336.         then
  337.             sed </tmp/$$ \
  338.             -e "s/ / raw /" \
  339.             -e "s/^/$tblespace /"
  340.         else
  341.             echo "$prog: lv botch, cannot find specification for $dev" >/tmp/$$.err
  342.             break
  343.         fi
  344.         ;;
  345.         *)
  346.         echo $tblespace $dev $type
  347.         ;;
  348.     esac
  349.     done \
  350.     | sed -e 's,/dev/rdsk/,,' \
  351.     | nawk '
  352. $3 == "raw"    { if (NF == 5)
  353.              printf "%s Oracle['$ORACLE_SID'] %s %s %s\n",$2,$1,$4,$5
  354.           else
  355.              printf "%s Oracle['$ORACLE_SID'] %s\n",$2,$1
  356.         }' \
  357.     | sort +0 -1 >/tmp/$$.ora
  358.     $DEBUG && cp /tmp/$$.ora _ora
  359.  
  360.     if [ -f /tmp/$$.err ]
  361.     then
  362.     cat /tmp/$$.err
  363.     status=1
  364.     exit
  365.     fi
  366.  
  367.     join -a1 -o 1.1 1.2 1.3 1.4 1.5 1.6 2.2 2.3 /tmp/$$.map /tmp/$$.ora >/tmp/$$
  368.     sort +0 -1 /tmp/$$ >/tmp/$$.map
  369.     $DEBUG && cp /tmp/$$.map _map.6
  370. fi
  371.  
  372. #
  373. # heuristic to remove partitions from vtoc that are not used and
  374. # overlap partitions that are used
  375. #
  376. sed </tmp/$$.map \
  377.     -e 's/\([0-9]\)s\([0-9]\)/\1 s\2/' \
  378. | sort +0 -1 +3n -4 +6r \
  379. | nawk '
  380. $1 != dk || $4 != start        { if ($1 != dk || $4 > end) {
  381.                     dk = $1; start = $4; end = $5; used = 0
  382.                   }
  383.                 }
  384. NF >= 6                { used = 1 }
  385. NF == 5 && used == 1        { next }
  386.                 { print }' \
  387. | sed -e 's/ s/s/' \
  388. | sort +0 -1 -o /tmp/$$.map
  389. $DEBUG && cp /tmp/$$.map _map.7
  390.  
  391. #
  392. # summary report
  393. #
  394. echo "dkmap for `/usr/bsd/hostname` on `date`"
  395. echo ""
  396.  
  397. sort +0 -1 +2n -3 +3n -4 /tmp/$$.map \
  398. | sed \
  399.     -e 's/\([^ ]*[0-9][0-9]*d[0-9][0-9]*\)s/\1 &/' \
  400.     -e '/lvol/s/!config/lv not configured/' \
  401.     -e '/xlv/s/!config/xlv not configured/' \
  402. | nawk '
  403. BEGIN    { print "Partition    Type or lv Start Blk   End Blk  Size(Mb)  Use" }
  404.     { if ($1 != last && last != "") print ""
  405.       last = $1
  406.       type = $3
  407.       if ($6 == "swap") type = "swap"
  408.       else if ($6 ~ /^Oracle/) type = "ora"
  409.       if ($1 ~ /^rad/) type = "raid"
  410.       printf "%-12s %10s %9d %9d %9d  %s %s %s\n",$2,type,$4,$5,int(0.5+($5+1-$4)/2048),$6,$7,$8
  411.     }'
  412.  
  413. exit
  414.